package org.jflame.context.spring;

import java.time.Duration;

import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.util.StringUtils;

/**
 * 自定义RedisCacheManager使用得注解上可以自定义有效期,在cacheNames上设置有效期,格式:cacheNames#1[d|h|m|s],如缓存2分钟cachename#2m.
 * <p>
 * 示例(设置缓存时间为1小时 ): <pre>
 * <code>
 * &#64;Cacheable(cacheNames = "grade#1h",key = "'cachekey'")
 * public void getGrade(){//do somthing}
 * </code> </pre>
 * 
 * @author charles.zhang
 */
public class MyRedisCacheManager extends RedisCacheManager {

    public MyRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
        super(cacheWriter, defaultCacheConfiguration);
    }

    @Override
    protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
        String[] array = StringUtils.delimitedListToStringArray(name, "#");
        name = array[0];
        if (array.length > 1) { // 解析TTL
            // 例如 12 默认12秒， 12d=12天
            String ttlStr = array[1];
            Duration duration = convertDuration(ttlStr);
            cacheConfig = cacheConfig.entryTtl(duration);
        }
        return super.createRedisCache(name, cacheConfig);
    }

    private Duration convertDuration(String ttlStr) {
        if (NumberUtils.isParsable(ttlStr)) {
            return Duration.ofSeconds(Long.parseLong(ttlStr));
        }
        // name#12s 标识12秒过期(d=天,h=小时,m=分钟,s秒)
        ttlStr = ttlStr.toUpperCase();

        if (ttlStr.lastIndexOf("D") != -1) {
            return Duration.parse("P" + ttlStr);
        }

        return Duration.parse("PT" + ttlStr);
    }

}
